package org.example.shuqing.expression;

import cn.hutool.core.date.StopWatch;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.io.resource.Resource;
import com.oracle.truffle.js.scriptengine.GraalJSEngineFactory;
import com.oracle.truffle.js.scriptengine.GraalJSScriptEngine;

import javax.script.Bindings;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import java.nio.charset.Charset;

/**
 *  利用 GraalJs 调用js
 * 引擎的开始和初始化
 * @author wangshuqing
 */
public class GraalJsDemo {

    private static String DEFAULT_FUNCTION="";


    static {
        try {
            init();
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }
    /***
    * 将自定义的js函数加载到内存中
     * 这里可以自定义一些，js 的函数，也可以引用更多其他的js库
    * @date 2022/11/21 15:13
    * @author wangshuqing
    * */
    public static void init() throws ScriptException {
        //自定义的文件位置
        Resource resource = new ClassPathResource("my-test.js");
        DEFAULT_FUNCTION = IoUtil.read(resource.getStream(), Charset.defaultCharset());
    }

    /***
    * 调用引擎返回结果
    * @date 2022/11/21 15:25
    * @author wangshuqing
    * */
    public static Object eval(String script,Bindings params) throws ScriptException {
        GraalJSScriptEngine engine = buildEngine();
        if(params==null){
            params=new SimpleBindings();
        }
        Bindings bindings =null;
        if(params !=null){
            bindings = engine.createBindings();
            //将参数给构建到全局，TODO 这块应该有别的方法更好
            engine.eval(DEFAULT_FUNCTION,bindings);
            bindings.putAll(params);
        }
        return engine.eval(script,bindings);
    }

    /***
    *  构建 GraalJS引擎
    * @date 2022/11/21 15:25
    * @author wangshuqing
    * */
    private static GraalJSScriptEngine buildEngine(){
        GraalJSEngineFactory graalJSEngineFactory = new GraalJSEngineFactory();
        GraalJSScriptEngine engine = graalJSEngineFactory.getScriptEngine();
        return engine;
    }




    public static void main(String[] args) throws Exception{

        StopWatch watch=new StopWatch();
        watch.start();
        Bindings params=new SimpleBindings();
        params.put("desc","wo.shi.desc");
        System.out.println(String.format("带参数输出结果：%s",eval("fn.getName(desc)",params)));
        watch.stop();
        System.out.println(String.format("耗时：%s",watch.getLastTaskTimeMillis()));

        StopWatch watchOne=new StopWatch();
        watchOne.start();
        System.out.println(String.format("不带参数的输出结果：%s,",eval("var a=1;var b=8; fn.sub(a,b)",null)));
        watchOne.stop();
        System.out.println(String.format("耗时：%s",watchOne.getLastTaskTimeMillis()));




    }



    






}
